package com.healthlogger;

import java.util.*;
import android.util.Log;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.hardware.*;

public class MainActivity extends Activity implements SensorEventListener {

	SensorManager sensorManager;
	float currentAcceleration = 0;
	float maxAcceleration = 0;
	Button start;
	Button stop;
	Button startService;
	Button stopService;
	TextView force;
	TextView hashCode;
	EditText uniqueId;
	Timer updateUITimer = null;
	Timer logTimer = null;
	String currentG = "";
	MainDatabase db;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.w("USER", "MainActivity.onCreate");
		setContentView(R.layout.main);
		
		/* UI components */
		start = (Button) findViewById(R.id.startBTN);
		stop = (Button) findViewById(R.id.stopBTN);
		startService = (Button) findViewById(R.id.startServiceBTN);
		stopService = (Button) findViewById(R.id.stopServiceBTN);
		force = (TextView) findViewById(R.id.force);
		uniqueId = (EditText) findViewById(R.id.uniqueID);
		hashCode = (TextView) findViewById(R.id.hashCode);
		/* Sensors */
		sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
		Sensor accelerometer = sensorManager
				.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		sensorManager.registerListener(sensorEventListener, accelerometer,
				SensorManager.SENSOR_DELAY_FASTEST);
		
		/*DB*/
		db = new MainDatabase(this);
		

		/* Listeners */
		//Start service clicked
		start.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Log.w("USER", "Start clicked");
				if (uniqueId.getText().toString().equals("")) {
					System.out.println("toast");
					showToastWithMessage("You must enter a unique ID, before starting");
				} else {
					startUITimer();
					startLogging();
					
				}

			}
		});

		//Stop clicked
		stop.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Log.w("USER", "Stop clicked");
				stopUITimer();
				stopLogging();
				Intent intent = new Intent(Intent.ACTION_SEND); 
				intent.setType("plain/text");
				intent.putExtra(Intent.EXTRA_EMAIL,new String []{"dk.iha.sensorlogger@gmail.com"});  
				intent.putExtra(Intent.EXTRA_SUBJECT, "Log for the last 24 hours"); 
				intent.putExtra(Intent.EXTRA_TEXT, db.getLogItems().toString()); 
				startActivity(Intent.createChooser(intent, "dk.iha.sensorlogger"));
				//closes application
				//finish();
			}
		});

		//Stop service clicked
		stopService.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Log.w("USER", "Stop service clicked");
				//stop the service
				stopService(new Intent(MainActivity.this, MainService.class));
			}
		});

		//Start service clicked
		startService.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Log.w("USER", "Stop service clicked");
				//Start the service
				explicitStart();
			}
		});
	}

	protected void onDestroy() {
		// TODO Auto-generated method stub
		Log.w("USER", "MainActivity.onDestroy");

		super.onDestroy();
	}

	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		Log.w("USER", "MainActivity.onStart");
		hashCode.setText(String.valueOf(this.hashCode()));//this.hashCode());
		super.onStart();
	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		Log.w("USER", "MainActivity.onPause");
		super.onPause();
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		Log.w("USER", "MainActivity.onResume");
		super.onResume();
	}

	private void startUITimer() {
		updateUITimer = new Timer("gForceUpdate");
		updateUITimer.scheduleAtFixedRate(new TimerTask() {
			public void run() {
				updateGUI();
			}
		}, 0, 100);
	}
	
	private void stopUITimer() {
		//check if timer is running/instatiated
		if(null != updateUITimer)
			updateUITimer.cancel();
	}
	
	private void startLogging(){
		logTimer = new Timer();
		logTimer.scheduleAtFixedRate(new TimerTask() {
			@Override
			public void run() {
				Log.w("LOGGING", "Log entry!");
				long test = db.addNewLogEntry(new LogItem(uniqueId.getText().toString(),new Date().toString(),currentG,"latitude","longitude"));//TODO - add latitude & longitude
				Log.w("new entry: ", "id: " + test );
			}
		}, 0, 2000);
	}
	
	private void stopLogging(){
		if(null != logTimer){
			Log.w("LOGGING", "Stopped!!");
			db.getLogItems();
			logTimer.cancel();
		}
	}

	private void showToastWithMessage(String message) {
		Context context = getApplicationContext();
		CharSequence text = message;
		int duration = Toast.LENGTH_SHORT;
		Toast toast = Toast.makeText(context, text, duration);
		toast.setGravity(Gravity.CENTER_HORIZONTAL|Gravity.CENTER_VERTICAL, 0, 0);
		toast.show();
	}

	

	private final SensorEventListener sensorEventListener = new SensorEventListener() {
		double calibration = SensorManager.STANDARD_GRAVITY;

		public void onAccuracyChanged(Sensor sensor, int accuracy) {
		}

		public void onSensorChanged(SensorEvent event) {
			double x = event.values[0];
			double y = event.values[1];
			double z = event.values[2];

			double a = Math.round(Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)
					+ Math.pow(z, 2)));
			currentAcceleration = Math.abs((float) (a - calibration));

			if (currentAcceleration > maxAcceleration)
				maxAcceleration = currentAcceleration;
		}
	};

	private void updateGUI() {
		runOnUiThread(new Runnable() {
			public void run() {
				currentG = currentAcceleration
						/ SensorManager.STANDARD_GRAVITY + "Gs";
				force.setText(currentG);
				
				/*Max G - currently not used!!!*/
				//String maxG = maxAcceleration / SensorManager.STANDARD_GRAVITY
				//		+ "Gs";
			}
		});
	};
	
	

	public void onAccuracyChanged(android.hardware.Sensor arg0, int arg1) {
		// TODO Auto-generated method stub
	}

	public void onSensorChanged(SensorEvent arg0) {
		// TODO Auto-generated method stub
	}

	
	
	//Explicitly start this service
	private void explicitStart() {
		Log.w("USER", "MainActivity.explicitStart");
		// Explicitly start My Service
		Intent intent = new Intent(this, MainService.class);
		// Starts the service explicit (then it is not torn down when the activity ends)
		startService(intent);
		//Bind the service to the activity
		bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
	}
	
	// Reference to the service STARTS
	private MainService serviceRef = null;
	// Handles the connection between the service and activity
	private ServiceConnection mConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className,
				IBinder service) {
			// Called when the connection is made.
			serviceRef = ((MainService.MyBinder)service).getService();
			Log.w("USER", "MainActivity.onServiceConnected");
		}
		public void onServiceDisconnected(ComponentName className) {
			// Received when the service unexpectedly disconnects.
			serviceRef = null;
			Log.w("USER", "MainActivity.onServiceDisconnected");
		}
	};
	// Reference to the service STOPS
}